
import BaseService from '@/utils/base/service';
import { LoginModel } from '@/pages/login/model'; // 导入 LoginModel
import LoginManager from '@/pages/login/manager';

const BASE_URL = 'http://59.110.159.111/zhct';
const UPLOAD = '/sys/oss/upload'

interface RequestOptions {
	url : string;
	method ?: 'GET' | 'POST' | 'PUT' | 'DELETE';
	headers ?: Record<string, string>;
	data ?: any;
	timeout ?: number;
	showLoading ?: boolean;
	query ?: boolean;
}

// 默认请求头配置
const DEFAULT_HEADERS : Record<string, string> = {
	'Content-Type': 'application/json',
	'Authorization': 'Bearer token', // 示例：固定的认证 token
};

// 获取动态 appToken
const fetchAppToken = () : string => {
	const cacheData = new LoginModel().loadCache();
	return cacheData?.token || ''; // 如果存在用户 token，则返回 token，否则返回空字符串
};

/**
 * 显示加载指示器
 */
const showLoadingIndicator = (title : string = '', mask : boolean = false) : void => {
	uni.showLoading({
		title,
		mask,
	});
};

/**
 * 隐藏加载指示器
 */
const hideLoadingIndicator = () : void => {
	uni.hideLoading();
};

/**
 * 打印请求详细信息
 * @param url - 请求的 URL
 * @param options - 请求选项
 * @param headers - 请求头信息
 */
const logRequestDetails = (url : string, options : RequestOptions, headers : Record<string, string>) : void => {
	console.log(`请求 URL: ${url}`);
	console.log(`请求方法: ${options.method}`);
	console.log('请求参数:', JSON.stringify(options.data, null, 2));
	console.log('请求头:', JSON.stringify(headers, null, 2));
};

/**
 * 打印响应信息
 * @param url - 请求的 URL
 * @param response - 响应数据
 */
const logResponseDetails = (url : string, response : any) : void => {
	console.log(`响应 URL: ${url}`);
	console.log('响应数据:', JSON.stringify(response, null, 2));
};

/**
 * 发起通用请求
 * @param options - 请求选项
 * @returns Promise，返回请求结果
 */
const makeRequest = (options : RequestOptions) : Promise<any> => {
	// 判断 fileUrl 是否以 http 或 https 开头，如果不是则拼接 BASE_URL
	let requestUrl = /^https?:\/\//.test(options.url) ? options.url : `${BASE_URL}${options.url}`;
	const headers = { ...DEFAULT_HEADERS, ...options.headers, appToken: fetchAppToken() };
	if (options.query && options.data) {
		const queryString = Object.keys(options.data)
			.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(options.data[key]))
			.join('&');
		requestUrl = requestUrl.includes('?') ? `${requestUrl}&${queryString}` : `${requestUrl}?${queryString}`;
	}
	logRequestDetails(requestUrl, options, headers); // 打印请求详细信息
	if (options.showLoading != false) {
		showLoadingIndicator(); // 显示加载指示器
	}
	return new Promise((resolve, reject) => {
		uni.request({
			url: requestUrl,
			method: options.method || 'GET',
			header: headers, // 添加 appToken 到请求头
			data: options.data || {},
			timeout: options.timeout || 5000,
			success: (res) => {
				const responseData = BaseService.parseResponse(res.data); // 使用 BaseResponse 类型解析数据
				logResponseDetails(requestUrl, res); // 打印响应信息
				if (responseData.code === 0) {
					resolve(responseData);
				} else {
					if (responseData.code === 401 && fetchAppToken().length !== 0) {
						LoginManager.getInstance().logout();
						uni.showModal({
							title: '提示',
							content: '当前登录已失效，请重新登录！',
							showCancel: false,
							confirmColor: '#CBAB7C',
							success: function (res) {
								if (res.confirm) {
									uni.reLaunch({
										url: '/pages/homepage/index',
									});
								}
							}
						});
					}
					console.error(`请求 URL ${requestUrl} 返回错误，错误信息:`, responseData.msg);
					reject({ code: responseData.code, msg: responseData.msg, data: responseData.data });
				}
			},
			fail: (error) => {
				console.error(`请求 URL ${requestUrl} 失败，错误信息:`, error); // 打印请求失败的错误信息
				uni.showToast({ title: '请求失败，请重试', icon: 'error' });
				reject({ code: 500, msg: '请求失败', data: null });
			},
			complete: () => {
				console.log(`请求 URL ${requestUrl} 完成`); // 打印请求完成日志
				if (options.showLoading != false) {
					hideLoadingIndicator(); // 隐藏加载指示器
				}
			},
		});
	});
};

/**
 * 上传文件方法
 * @param filePath 要上传的文件路径
 * @returns 返回一个 Promise，上传成功返回文件的 URL，失败则返回错误信息
 */
const uploadFile = (filePath : string) : Promise<string> => {
	const requestUrl = `${BASE_URL}${UPLOAD}`; // 固定的上传接口地址
	const fileName = `${Date.now()}${Math.floor(Math.random() * 90000 + 10000)}`; // 生成文件名：时间戳 + 5位随机数
	const headers = { appToken: fetchAppToken() };

	logRequestDetails(requestUrl, { url: requestUrl, method: 'POST', data: { fileName, filePath } }, headers); // 打印请求详细信息

	showLoadingIndicator('上传中...', true);

	return new Promise((resolve, reject) => {
		console.log('文件上传 开始'); // 上传文件开始日志

		uni.uploadFile({
			url: requestUrl,
			filePath: filePath,
			name: 'file',
			formData: { fileName },
			header: headers,
			success: (res) => {
				try {
					const responseData = BaseService.parseResponse(res.data); // 使用 BaseResponse 类型解析数据
					if (responseData.code === 0) {
						console.log('文件上传 成功，URL:', responseData.data); // 打印上传成功的文件 URL
						resolve(responseData.data); // 直接返回URL字符串
					} else {
						console.error('上传文件错误，服务器返回错误信息:', responseData.msg);
						reject(responseData.msg);
					}
				} catch (error) {
					console.error('返回数据解析错误:', error);
					reject('返回数据格式错误');
				}
			},
			fail: (error) => {
				console.error('上传文件失败，错误信息:', error);
				reject('上传失败');
			},
			complete: () => {
				console.log(`上传文件URL ${requestUrl} 完成`); // 打印上传文件完成日志
				hideLoadingIndicator();
			},
		});
	});
}

/**
 * 下载文件并保存到指定文件夹
 * @param fileUrl 文件的下载 URL
 * @param folderPath 文件保存的二级文件夹路径
 * @returns 返回一个 Promise，下载和保存成功时返回保存的文件路径，失败时返回错误信息
 */
const downloadFile = (fileUrl : string, filePath ?: string, fileName ?: string) : Promise<string> => {
	showLoadingIndicator('文件下载中...', true);
	// 判断 fileUrl 是否以 http 或 https 开头，如果不是则拼接 BASE_URL
	const requestUrl = /^https?:\/\//.test(fileUrl) ? fileUrl : `${BASE_URL}${fileUrl}`;
	const headers = { appToken: fetchAppToken() };
	logRequestDetails(requestUrl, { url: requestUrl, method: 'GET', data: {} }, headers); // 打印请求详细信息
	return new Promise((resolve, reject) => {
		// 下载文件
		uni.downloadFile({
			url: requestUrl,
			header: headers,  // 添加 appToken 到请求头
			success: (downloadRes) => {
				if (downloadRes.statusCode === 200) {
					const tempFilePath = downloadRes.tempFilePath; // 下载成功后，文件的临时路径
					console.log(`文件下载成功，临时文件路径：${tempFilePath}`);
					const lastElement = fileUrl.split('.').pop();
					// 保存文件到指定文件夹
					const locFileName = fileName ? fileName : `${Date.now()}-${Math.floor(Math.random() * 90000 + 10000)}${lastElement ? '.' + lastElement : ''}`; // 生成文件名
					const saveFilePath = `${wx.env.USER_DATA_PATH}/${filePath ? filePath + '/' : ''}${locFileName}`; // 保存的路径
					uni.saveFile({
						tempFilePath: tempFilePath,  // 下载的临时文件路径
						filePath: saveFilePath,      // 目标保存路径
						success: (saveRes) => {
							logResponseDetails(requestUrl, saveRes); // 打印保存文件的结果
							resolve(saveRes.savedFilePath);  // 返回保存后的文件路径
						},
						fail: (error) => {
							console.error('文件保存失败：', error);
							reject('文件保存失败');
						},
					});
				} else {
					console.error('文件下载失败，状态码：', downloadRes.statusCode);
					reject('文件下载失败');
				}
			},
			fail: (error) => {
				console.error('下载文件失败：', error);
				reject('下载文件失败');
			},
			complete: () => {
				hideLoadingIndicator(); // 隐藏加载指示器
				console.log(`下载文件 URL ${requestUrl} 完成`);
			},
		});
	});
};

export default makeRequest;
export { uploadFile, downloadFile };